{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(47, 3) <class 'numpy.ndarray'>\n",
      "(47, 1) <class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "def normalize_feature(df):\n",
    "    return df.apply(lambda column: (column - column.mean()) / column.std())\n",
    "\n",
    "\n",
    "df = normalize_feature(pd.read_csv('data1.csv',\n",
    "                                   names=['square', 'bedrooms', 'price']))\n",
    "\n",
    "ones = pd.DataFrame({'ones': np.ones(len(df))})# ones是n行1列的数据框，表示x0恒为1\n",
    "df = pd.concat([ones, df], axis=1)  # 根据列合并数据\n",
    "\n",
    "X_data = np.array(df[df.columns[0:3]])\n",
    "y_data = np.array(df[df.columns[-1]]).reshape(len(df), 1)\n",
    "\n",
    "print(X_data.shape, type(X_data))\n",
    "print(y_data.shape, type(y_data))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\ProgramData\\Anaconda3\\envs\\tensorflow112\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:523: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n",
      "D:\\ProgramData\\Anaconda3\\envs\\tensorflow112\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:524: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n",
      "D:\\ProgramData\\Anaconda3\\envs\\tensorflow112\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n",
      "D:\\ProgramData\\Anaconda3\\envs\\tensorflow112\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n",
      "D:\\ProgramData\\Anaconda3\\envs\\tensorflow112\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:527: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n",
      "D:\\ProgramData\\Anaconda3\\envs\\tensorflow112\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:532: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "\n",
    "alpha = 0.01 # 学习率 alpha\n",
    "epoch = 500 # 训练全量数据集的轮数\n",
    "\n",
    "with tf.name_scope('input'):\n",
    "    # 输入 X，形状[47, 3]\n",
    "    X = tf.placeholder(tf.float32, X_data.shape, name='X')\n",
    "    # 输出 y，形状[47, 1]\n",
    "    y = tf.placeholder(tf.float32, y_data.shape, name='y')\n",
    "\n",
    "with tf.name_scope('hypothesis'):\n",
    "    # 权重变量 W，形状[3,1]\n",
    "    W = tf.get_variable(\"weights\",\n",
    "                        (X_data.shape[1], 1),\n",
    "                        initializer=tf.constant_initializer())\n",
    "    # 假设函数 h(x) = w0*x0+w1*x1+w2*x2, 其中x0恒为1\n",
    "    # 推理值 y_pred  形状[47,1]\n",
    "    y_pred = tf.matmul(X, W, name='y_pred')\n",
    "\n",
    "with tf.name_scope('loss'):\n",
    "    # 损失函数采用最小二乘法，y_pred - y 是形如[47, 1]的向量。\n",
    "    # tf.matmul(a,b,transpose_a=True) 表示：矩阵a的转置乘矩阵b，即 [1,47] X [47,1]\n",
    "    # 损失函数操作 loss\n",
    "    loss_op = 1 / (2 * len(X_data)) * tf.matmul((y_pred - y), (y_pred - y), transpose_a=True)\n",
    "with tf.name_scope('train'):\n",
    "    # 随机梯度下降优化器 opt\n",
    "    train_op = tf.train.GradientDescentOptimizer(learning_rate=alpha).minimize(loss_op)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 100 \t Loss=0.1835 \t Model: y = 0.4909x1 + 0.1621x2 + -6.147e-10\n",
      "Epoch 200 \t Loss=0.1483 \t Model: y = 0.6678x1 + 0.1255x2 + 2.119e-10\n",
      "Epoch 300 \t Loss=0.1379 \t Model: y = 0.7522x1 + 0.07118x2 + 5.087e-10\n",
      "Epoch 400 \t Loss=0.1337 \t Model: y = 0.8004x1 + 0.02938x2 + 1.694e-09\n",
      "Epoch 500 \t Loss=0.132 \t Model: y = 0.8304x1 + 0.0008239x2 + 4.138e-09\n"
     ]
    }
   ],
   "source": [
    "with tf.Session() as sess:\n",
    "    # 初始化全局变量\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "    # 创建FileWriter实例，并传入当前会话加载的数据流图\n",
    "    writer = tf.summary.FileWriter('./summary/linear-regression-1', sess.graph)\n",
    "    # 记录所有损失值\n",
    "    loss_data = []\n",
    "    # 开始训练模型\n",
    "    # 因为训练集较小，所以采用批梯度下降优化算法，每次都使用全量数据训练\n",
    "    for e in range(1, epoch + 1):\n",
    "        _, loss, w = sess.run([train_op, loss_op, W], feed_dict={X: X_data, y: y_data})\n",
    "        # 记录每一轮损失值变化情况\n",
    "        loss_data.append(float(loss))\n",
    "        if e % 100 == 0:\n",
    "            log_str = \"Epoch %d \\t Loss=%.4g \\t Model: y = %.4gx1 + %.4gx2 + %.4g\"\n",
    "            print(log_str % (e, loss, w[1], w[2], w[0]))\n",
    "\n",
    "# 关闭FileWriter的输出流\n",
    "writer.close()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "500\n"
     ]
    }
   ],
   "source": [
    "print(len(loss_data))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "sns.set(context=\"notebook\", style=\"whitegrid\", palette=\"dark\")\n",
    "\n",
    "ax = sns.lineplot(x='epoch', y='loss', data=pd.DataFrame({'loss': loss_data, 'epoch': np.arange(epoch)}))\n",
    "ax.set_xlabel('epoch')\n",
    "ax.set_ylabel('loss')\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "name": "tensorflow112",
   "language": "python",
   "display_name": "tensorflow112"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}